package main

import (
	"encoding/json"
	"fmt"
	"gopkg.in/ini.v1"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
)

var (
	cfg *ini.File
	err error
)

type Post struct {
	Name       string
	Ref        string
	Repository map[string]interface{}
}

func main() {
	// 加载配置文件
	cfg, err = ini.Load("auto-deploy.ini")

	cfgPort := cfg.Section("").Key("PORT").String()
	if cfgPort == "" {
		cfgPort = "8000"
	}

	http.HandleFunc("/", myHandle)
	err := http.ListenAndServe(":"+cfgPort, nil)
	if err != nil {
		fmt.Printf("http.ListenAndServe() error:%v\n", err)
		return
	}
}

func myHandle(w http.ResponseWriter, r *http.Request) {
	/*fmt.Println(r.Header["Content-Type"])
	r.ParseForm()
	fmt.Println(r.Form)*/

	root := strings.TrimRight(r.FormValue("root"), "/")
	if root == "" {
		w.Write([]byte("arguments root error"))
		return
	}
	//fmt.Println("root:", root)

	// github
	password := r.PostFormValue("password")
	if password != "" {
		if password != cfg.Section("").Key("PASSWORD").String() {
			w.Write([]byte("arguments password error"))
			return
		}
	}
	//fmt.Println("password:", password)

	// 阿里云效
	token := r.Header.Get("X-Codeup-Token")
	if token != "" {
		if token != cfg.Section("").Key("TOKEN").String() {
			w.Write([]byte("arguments token error"))
			return
		}
	}
	/*formData := make(map[string]interface{})
	// 调用json包的解析，解析请求body
	json.NewDecoder(r.Body).Decode(&formData)
	fmt.Println(formData)*/

	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Println(err)
	}
	data := Post{}
	json.Unmarshal([]byte(b), &data)
	//fmt.Fprintf(w, "%#v\n", data) // 格式化输出结果

	ref := r.PostFormValue("ref")
	if ref == "" {
		ref = data.Ref
	}
	branch := strings.Split(ref, "/")[2]
	cfgBranch := cfg.Section("").Key("BRANCH").String()
	if cfgBranch == "" {
		cfgBranch = "develop"
	}
	if branch != cfgBranch {
		w.Write([]byte("this branch cannot be deployed automatically,Only the development branch can deploy fields"))
		return
	}

	sshUrl := r.PostFormValue("project[ssh_url]")
	if sshUrl == "" {
		sshUrl = data.Repository["git_ssh_url"].(string)
	}
	//fmt.Println(root, sshUrl, branch)

	go pull(root, sshUrl, branch)
	// 回复
	w.Write([]byte("success"))
}

func pull(path string, sshUrl string, branch string) {
	//fmt.Println("拉取代码", path, sshUrl, branch)
	dir := strings.Split(path, "/")
	dir1 := strings.Join(dir[0:len(dir)-1], "/")
	dir2 := dir[len(dir)-1]
	if IsExist(path) {
		cmd := exec.Command("/bin/bash", "-c", "cd "+path+" && git checkout "+branch+" && git pull")
		out, err := cmd.CombinedOutput()
		if err != nil {
			fmt.Println("pull:", err.Error())
			fmt.Println("pull:", string(out))
			return
		}
		cmd.Run()
	} else {
		cmd := exec.Command("/bin/bash", "-c", "cd "+dir1+" && git clone "+sshUrl+" "+dir2+" && cd "+dir2+" && git checkout -b develop origin/develop")
		out, err := cmd.CombinedOutput()
		if err != nil {
			fmt.Println("clone:", err.Error())
			fmt.Println("clone:", string(out))
			return
		}
		cmd.Run()
	}
	//fmt.Println("pull 成功")
	composer(path)
}

func composer(path string) {
	if IsExist(path + "/composer.json") {
		cmd := exec.Command("/bin/bash", "-c", "cd "+path+" && composer install")
		//out, _ := cmd.CombinedOutput()
		//fmt.Println("composer:",string(out))
		cmd.Run()
		//fmt.Println("包更新成功")
	}
}

func IsExist(path string) bool {
	_, err := os.Stat(path)
	return err == nil || os.IsExist(err)
}
